package com.kk.datastructure.array;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SparseArray {

	/**
	 * @param args
	 */
	/**
	 * @param args
	 */
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// 创建一个原始棋牌 大小为 11*11
		// 1 黑棋子 ， 2 白棋子 ，0 无棋子
		int chessArr1[][] = new int[11][11];
		// 随便下几颗棋子
		chessArr1[1][2] = 1;
		chessArr1[3][4] = 2;
		chessArr1[5][7] = 1;
		// 输出原始二位数组（棋牌）
		System.out.println("输出我的棋牌：");
		// 遍历
		ergodic(chessArr1);
		System.out.println("------------------------------------美丽的分割线-----------------------------------");

		// 二位数组转换为稀疏数组
		// 思路：
		// 1、首先注意的是，行和列这里设计都从零开始（因为遍历我打算从0开始）
		// 2、遍历原始二位数组，获取到有效值个数 sum（有效值：就是除了初始化0值以外的）
		// 3、再根据 sum 创建出 稀疏数组 长度 sparsearray[sum+1][3]（可以理解就理解，不行就当公式记下来）
		// 4、将要二位数组的有效数据存放到稀疏数组中（有效数据：行，列，值）

		// 步骤一：
		int sum = 0;
		for (int row[] : chessArr1) {
			for (int data : row) {
				if (data != 0) {
					sum++;
				}
			}
		}
		System.out.println("得到的有效值总个数：" + sum);

		// 步骤二：
		int sparseArray[][] = new int[sum + 1][3];
		// 给稀疏数组的有效数据 初始化
		sparseArray[0][0] = 11;
		sparseArray[0][1] = 11;
		sparseArray[0][2] = sum;

		// 遍历原始二位数组，将有效棋子（非0）放入sparseArray
		// i表示 行，j表示列
		int count = 0; // 记录有效棋子
		for (int i = 0; i < chessArr1.length; i++) {
			for (int j = 0; j < chessArr1.length; j++) {
				if (chessArr1[i][j] != 0) {
					count++;
					sparseArray[count][0] = i;
					sparseArray[count][1] = j;
					sparseArray[count][2] = chessArr1[i][j];
				}
			}
		}
		System.out.println("稀疏数组：");
		ergodic(sparseArray);
		System.out.println("------------------------------------美丽的分割线-----------------------------------");

		// 稀疏数组转原始数组 行*列
		int chessArr2[][] = new int[sparseArray[0][0]][sparseArray[0][1]];
		// 第二行开始赋值
		for (int i = 1; i < sparseArray.length; i++) {
			// 表示 ： 稀疏的每行的有效值 ，复制给 原始行列
			chessArr2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
		}
		// 遍历
		System.out.println("还原二位数组");
		ergodic(chessArr2);

		// 稀疏序列化
		sparseSerialize(sparseArray);
		
		// 稀疏反序列化
		int[][] arr =  (int[][])sparseDSerialize(resourcePath);
		System.out.println("最后得到类class类型"+arr.getClass().getName());
		ergodic(arr);
				
	}

	// 遍历工具类
	private static void ergodic(int[][] array) {
		for (int row[] : array) {
			for (int data : row) {
				System.out.printf("%d\t", data);
			}
			System.out.println();
		}
	}

	public  final static String    resourcePath = "F:\\STS_cunfang\\数据结构和算法\\src\\com\\kk\\datastructure\\array\\sparseSerialize.txt";
	
	// 序列化工具类
	private static void sparseSerialize(int[][] array) {
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream(resourcePath));
			oos.writeObject(array);
			oos.flush();
		} catch (Exception e) {
			e.getStackTrace();
		} finally {
			try {
				oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	// 序列化工具类
	private static Object  sparseDSerialize(String path)  {
		ObjectInputStream ois = null;
		Object arr = null;
		try {
			ois = new ObjectInputStream(new FileInputStream(resourcePath));
			arr = ois.readObject();
			return arr;		
		} catch (Exception e) {
			e.getStackTrace();
		}finally {
			try {
				ois.close();
			} catch (Exception e2) {
				e2.getStackTrace();
			}
		}
		return null;		
	}
}
